
/**********************************************************************************************************************
  COPYRIGHT
-----------------------------------------------------------------------------------------------------------------------
  \par      copyright
  \verbatim
  Copyright (c) 2017 by Vector Informatik GmbH.                                                  All rights reserved.

                This software is copyright protected and proprietary to Vector Informatik GmbH.
                Vector Informatik GmbH grants to you only those rights as set out in the license conditions.
                All other rights remain with Vector Informatik GmbH.
  \endverbatim
-----------------------------------------------------------------------------------------------------------------------
  FILE DESCRIPTION
-----------------------------------------------------------------------------------------------------------------------
  \file  File:  BrsAsrMain.c
      Project:  Vector Basic Runtime System for MICROSAR4
       Module:  BrsAsrMain

  \brief Description:  Main File of BrsAsr4 contains
                       - Main function (start of initialization (EcuM)
                       - InitTask, Main and Background Task which can be used by the operating system
                       - Exception handling

  \attention Please note:
    The demo and example programs only show special aspects of the software. With regard to the fact
    that these programs are meant for demonstration purposes only, Vector Informatik liability shall be
    expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute.
**********************************************************************************************************************/

/**********************************************************************************************************************
  AUTHOR IDENTITY
 ----------------------------------------------------------------------------------------------------------------------
  Name                          Initials      Company
  ----------------------------  ------------  -------------------------------------------------------------------------
  Benjamin Walter               visbwa        Vector Informatik GmbH
  Andreas Hahn                  vishan        Vector Informatik GmbH
-----------------------------------------------------------------------------------------------------------------------
  REVISION HISTORY
 ----------------------------------------------------------------------------------------------------------------------
  Version   Date        Author  Description
  --------  ----------  ------  ---------------------------------------------------------------------------------------
  01.00.00  2014-02-03  visbwa  Initial creation of new BrsAsr4 code basis
  01.00.01  2014-04-11  visbwa  Removed DeclareTask() calls as this is not needed by AsrOs
  01.00.02  2014-08-19  visbwa  Added for SafeContext and/or MultiCore OS (inclusive MemMap usage),
                                added legal wording within header information
  01.00.03  2014-09-11  visbwa  Encapsulated mainTask and backgroundTask to be configuration dependent,
                                added support for UseCase w/o OS
  01.00.04  2014-10-16  visbwa  IdleTask_Core0 renamed to IdleTask and always available with OS-support (for new OS),
                                osInitialize() always called with OS-support,
                                added support for MultiCore SafeWatchdog Stack
  01.00.05  2014-10-20  visbwa  encapsulated OS Hook templates by BRSASR_ENABLE_OSSUPPORT,
                                eliminated use of BRS_ENABLE_TIMER_INTERRUPT
  01.00.06  2015-02-06  visbwa  Replaced MSEC by OS_MS2TICKS to support new OS versions
  01.00.07  2015-02-09  visbwa  Replaced OS_MS2TICKS by OS_MS2TICKS_SystemTimer and added error-check,
                                added call of BrsHwPreInitPowerOn (encapsulated by BRSHW_PREINIT_AVAILABLE)
  01.00.08  2015-03-12  visbwa  Encapsuled call of BrsHwSetLed() with BRS_ENABLE_SUPPORT_LEDS
  01.00.09  2015-03-31  visbwa  Changed ECUM_CORE_ID_MASTER to ECUM_CORE_ID_STARTUP within main() for MultiCore
  01.00.10  2015-07-14  visbwa  Removed usage of v_cfg.h (replaced platform defines by compiler.h defines)
  01.01.00  2015-09-03  visbwa  Enhanced VTT support, removed CANoe-Emu support, added support of StartApplication,
                                removed OS-Hooks, as they are now generated by Os_Proxy within OS_Callout_Stubs.c
  01.01.01  2015-09-10  visbwa  Fixed VTT-filter bug (BrsAsrMainInit), 
                                added call of SchM_Init()(VTT-UseCase) and Rte_Start() to InitTasks for MultiCore
  01.01.02  2015-09-11  visbwa  Added sample for ESCAN00078832 workaround, fixed VTT MultiCore StartUp, 
                                included Rte_Main.h for MultiCore StartUp
  01.02.00  2015-10-06  visbwa  Enhanced TGF support, removed CpuLoad_Measurement
  01.02.01  2015-11-12  visbwa  Added call of osInitSlaveCore() for RH850 with MultiCore OS
  01.02.02  2015-11-26  visbwa  Fixed BRS_CPU_ defines to proper BRS_PLATFORM_ defines
  01.02.03  2015-12-02  visbwa  Readded CANoe-Emu support for Product/Program-Tests
  01.02.04  2015-12-09  visbwa  Added comment for RH850 OS function osInitINTC()
  01.02.05  2016-03-16  visbwa  Removed include of BrsAsrAppl.h for UseCase StartApplication,
                                fixed usage of zOs_Emu
  01.02.06  2016-03-23  visbwa  Added include of BrsAsrInit.h for UseCase BRSASR_ENABLE_SAFEWDGSUPPORT
  01.02.07  2016-03-30  visbwa  Fixed/disabled call of BrsHwTimeBaseInitPowerOn() in UseCase zOs_Emu
  01.02.08  2016-03-31  visbwa  Fixed initialization of gbBrsMainIsrMilliSecondFlag
  01.02.09  2016-05-24  visbwa  Introduced support for OsCoreGen7,
                                removed include of osekext.h (SafeContext), because Os.h should be sufficient anyway
  01.02.10  2016-06-13  visbwa  Fixed encapsulation of variables with BRS_ENABLE_SUPPORT_LEDS
  01.03.00  2016-08-18  vishan  Added support for TCM driver
  01.03.01  2016-09-27  visbwa  Fixed TCM support (mainTask also available, if LED-support switched off)
  01.03.02  2016-10-12  visbwa  Introduced support for OsCoreGen7 initialization
  01.03.03  2016-10-19  visbwa  Moved include of EcuM.h into BrsAsrMain.h
  01.03.04  2016-10-25  visbwa  Changed encapsulation of BrsHw timer handling to BRSHW_ENABLE_TIMER_INTERRUPT
  01.03.05  2016-12-13  vishan  Moved calls of Tcm_MainFunction() and Tcm_BackgroundFunction(),
                                added HLP Testsuite functions
  01.03.06  2016-12-21  visbwa  Fixed initialization of wBrsMainCallCounter10ms and encapsulation of mainTask
  01.03.07  2017-01-05  vishan  Added BrsTcc_MeasureCyclesPerDelayLoopInMSec() call in BrsAsrMainInit()
  01.03.08  2017-01-11  vishan  Changed encapsulation regarding BRS_ENABLE_HLPTEST_SUPPORT
  01.03.09  2017-04-06  visbwa  Removed call of osInitSlaveCore() for OsGen7@RH850
  01.03.10  2017-05-08  visbwa  Added call of CANoeAPI_ConsumeTicks() within backgroundTask for UseCase VTT
  01.03.11  2017-05-23  visbwa  Fixed encapsulation of backgroundTask within header
**********************************************************************************************************************/

/**********************************************************************************************************************
*  SAMPLE CODE ONLY
*  -------------------------------------------------------------------------------------------------------------------
*  This implementation is sample code and only intended to illustrate an example of a possible BSW implementation.
*  The implementation may not be complete and is not provided for use in production
*  without any modifications. If this sample code is used in any way, the customer shall test
*  this implementation as well as any of its modifications with diligent care.
*********************************************************************************************************************/

/**********************************************************************************************************************
  INCLUDES
**********************************************************************************************************************/
#include "BrsAsrMain.h"

#if defined (BRS_ENABLE_HLPTEST_SUPPORT)
# include "BrsTcc.h"
# include "HlpTest_Main.h"
#endif 

#if defined (BRSASR_ENABLE_SAFEWDGSUPPORT)
# include "WdgM.h"
#endif

#include "BrsHw.h"

#if defined (BRSASR_ENABLE_OS_MULTICORESUPPORT)
# include "Rte_Main.h"
#endif /*BRSASR_ENABLE_OS_MULTICORESUPPORT*/

#if defined (BRSASR_ENABLE_TGFSUPPORT)
# include "BrsTcc.h"
# include "TgfMain.h"
#endif

#if defined (BRS_ENABLE_TCM_SUPPORT)
# include "TcmDriver.h"
#endif

#if defined (BRSASR_ENABLE_SAFEWDGSUPPORT)
# include "BrsAsrInit.h"
#endif

/**********************************************************************************************************************
  VERSION CHECK
**********************************************************************************************************************/
#if ((BRSASRMAIN_MAJOR_VERSION != 1U) || \
     (BRSASRMAIN_MINOR_VERSION != 3U) || \
     (BRSASRMAIN_PATCH_VERSION != 11U))
  #error "Vendor specific version numbers of BrsAsrMain.c and BrsAsrMain.h are inconsistent"
#endif

/**********************************************************************************************************************
  LOCAL CONSTANT MACROS
**********************************************************************************************************************/
#define BRSMAIN_ERRORBUFFERSIZE    120

#if defined (BRSASR_ENABLE_OS_MULTICORESUPPORT)
# if !defined (ECUM_CORE_ID_STARTUP)
  /* compatibility to older EcuM versions */
  #define ECUM_CORE_ID_STARTUP ECUM_CORE_ID_MASTER
# endif
#endif /*BRSASR_ENABLE_OS_MULTICORESUPPORT*/

/**********************************************************************************************************************
  LOCAL FUNCTION MACROS
**********************************************************************************************************************/

/**********************************************************************************************************************
  LOCAL DATA TYPES AND STRUCTURES
**********************************************************************************************************************/

/**********************************************************************************************************************
  LOCAL DATA PROTOTYPES
**********************************************************************************************************************/
#if defined (BRS_ENABLE_SUPPORT_LEDS)
#define START_SEC_VAR_ZERO_INIT_16BIT
#include "MemMap.h"
/**
 * \var wBrsMainCallCounter1ms
 *      Counter for calls of the function BrsAsrMainCyclic1ms
 */
static uint16 wBrsMainCallCounter1ms;
#define STOP_SEC_VAR 
#include "MemMap.h"

#define START_SEC_VAR_ZERO_INIT_16BIT
#include "MemMap.h"
/**
 * \var bBrsMainToggleLedCounter
 *      Counter for LED toggling within BrsMainMilliSecondHandler
 */
static uint8 bBrsMainToggleLedCounter;
#define STOP_SEC_VAR
#include "MemMap.h"
#endif /*BRS_ENABLE_SUPPORT_LEDS*/

#if defined (BRS_ENABLE_TCM_SUPPORT)
#define START_SEC_VAR_ZERO_INIT_16BIT
#include "MemMap.h"
/**
 * \var wBrsMainCallCounter10ms
 *      Counter for calls of the function Tcm_MainFunction
 */
static uint16 wBrsMainCallCounter10ms;
#define STOP_SEC_VAR
#include "MemMap.h"
#endif /*BRS_ENABLE_TCM_SUPPORT*/

/**********************************************************************************************************************
  GLOBAL DATA
**********************************************************************************************************************/
#if defined (BRSHW_ENABLE_TIMER_INTERRUPT)
/**
 * \var gbBrsMainIsrMilliSecondFlag
 *      The BRS internal timing is based on a cyclic called function. The call 
 *      must be performed each 1ms. This is done by an endless loop polling 
 *      this variable for being '1'. The value is set to '1' by a periodic 
 *      interrupt function in the hardware dependent module HW_CTRL. The value 
 *      is cleared to '0', if the 1ms event has been handled. The separation of 
 *      hardware independent and hardware dependent parts is the only reason to 
 *      export this variable here.
 *      Values: 0, wait for next 1ms event; 1, 1ms event occured
 */
 volatile uint8 gbBrsMainIsrMilliSecondFlag;
#endif /*BRSHW_ENABLE_TIMER_INTERRUPT*/

/**********************************************************************************************************************
  LOCAL FUNCTION PROTOTYPES
**********************************************************************************************************************/
#if defined (BRS_ENABLE_SUPPORT_LEDS)
static void BrsAsrMainCyclic1ms(void);
#endif

/**********************************************************************************************************************
  LOCAL FUNCTIONS
**********************************************************************************************************************/

/**********************************************************************************************************************
   GLOBAL FUNCTIONS
 **********************************************************************************************************************/

/***********************************************************************************************************************
 *  BrsMainExceptionHandler
 **********************************************************************************************************************/
/*! \brief      This is the central exeption handler of BRS.
 *              All BRS modules and all CANbedded specific fatal error handler will
 *              call this API in case an assertion has failed.
 *
 *  \param[in]  ErrorCode shall hold the caller specific error code (uint8)
 *  \param[in]  ModuleCode shall describe the caller; please use the CI constant as parameter (uint8)
 *  \param[in]  LineNumber shall be the line where the assertion has failed, or, 
 *              if not available on caller location, the line where this API is 
 *              called from
 *  \param[out] -
 *  \return     -
 *
 *  \attention  This function implements an endless loop with locked interrupts.
 *              The recommendation is to set a breakpoint on top of this function 
 *              to see if any assertion has failed during the code execution.
 *
 *  \post       Due to an assertion has failed and the endless loop runs with
 *              locked global interrupts there will be no life after the call ...
 **********************************************************************************************************************/
void BrsMainExceptionHandler(uint8  ErrorCode, uint8  ModuleCode, uint16 LineNumber)
{
#if defined (BRSASR_ENABLE_SAFECTXSUPPORT)
  while(1)
  {}

#else

# if defined (_MICROSOFT_C_VTT_)
  char error[BRSMAIN_ERRORBUFFERSIZE];

  sprintf_s(error, BRSMAIN_ERRORBUFFERSIZE, "BrsMainExceptionHandler Code: [0x%x] ModuleCode: [0x%x] LineNumber: [0x%x]", ErrorCode, ModuleCode, LineNumber);

  CANoeAPI_WriteString(error);
  ShutdownOS(0);

# else
  volatile uint8 BrsMain_Continue;
  BrsMain_Continue = 0;
  BrsHwDisableInterrupt(); 
  while (BrsMain_Continue == 0) 
  { 
    /* Set BrsMain_Continue to 1 to continue here. 
     *  If the debugger is not able to show the stack properly, this mechanism can be used to find the
     *  source of the exception. */
	  BrsMain_Continue = 1;
  }
# endif /*_MICROSOFT_C_VTT_*/
#endif /*BRSASR_ENABLE_SAFECTXSUPPORT*/
}

#if defined (BRS_ENABLE_SUPPORT_LEDS)
/***********************************************************************************************************************
 *  BrsAsrMainCyclic1ms
 **********************************************************************************************************************/
/*! \brief      One millisecond handler for BrsMain 
 *               - Executes retransmission of BRS TCC messages
 *               - Toggling of LED (alive signal)
 *               - BRS Test code (1s cyclic negative TCC response message)
 *  \param[in]  -
 *  \param[out] -
 *  \return     -
 *  \context    Function is called each millisecond either from the main loop or from the BRS main task (TASK(mainTask))
 **********************************************************************************************************************/
static void BrsAsrMainCyclic1ms(void)
{
  wBrsMainCallCounter1ms++;

  if (wBrsMainCallCounter1ms == 500)
  {
    wBrsMainCallCounter1ms = 0;
    bBrsMainToggleLedCounter++;

    /* Cyclic - 500ms for LED */
    BrsHwSetLed(BRSHW_LED_SYSTEM_OK, (uint8) (bBrsMainToggleLedCounter & 0x01));
  }
}
#endif /*BRS_ENABLE_SUPPORT_LEDS*/

#if defined (BRS_ENABLE_SUPPORT_LEDS) || defined (BRS_ENABLE_TCM_SUPPORT) || defined (BRS_ENABLE_HLPTEST_SUPPORT)
/***********************************************************************************************************************
 *  mainTask
 **********************************************************************************************************************/
/*! \brief      mainTask executes the 1 millisecond handler if an operating system is used
 *              The function initiates calls to BrsAsrMainCyclic1ms
 *              
 *  \param[in]  -
 *  \param[out] -
 *  \return     -
 *  \context    The task is started once by the OS and activated by the OS event EvCyclicAlarm_1ms
 **********************************************************************************************************************/
TASK(mainTask)
{
# if defined (BRSASR_ENABLE_OSSUPPORT) || defined (BRSASR_ENABLE_OSEMULATION)
  EventMaskType ev;

  (void)SetRelAlarm(CyclicAlarm_1ms, OS_MS2TICKS_SystemTimer(1), OS_MS2TICKS_SystemTimer(1));
# endif

  for(;;)
  {
# if defined (BRSASR_ENABLE_OSSUPPORT) || defined (BRSASR_ENABLE_OSEMULATION)
    (void)WaitEvent(EvCyclicAlarm_1ms);
    (void)GetEvent(mainTask, &ev);
    (void)ClearEvent(ev);
    if(ev & EvCyclicAlarm_1ms)
    {
# else
    if (gbBrsMainIsrMilliSecondFlag > 0)
    {
      gbBrsMainIsrMilliSecondFlag = 0;
# endif
# if defined (BRS_ENABLE_TCM_SUPPORT)
    if (wBrsMainCallCounter10ms == 10)
    {
      wBrsMainCallCounter10ms = 0;
      Tcm_MainFunction();
    }
    wBrsMainCallCounter10ms++;
# endif
# if defined (BRS_ENABLE_SUPPORT_LEDS)
      /* 1ms event detected, call the ms handler */
      BrsAsrMainCyclic1ms();
# endif
# if defined (BRS_ENABLE_HLPTEST_SUPPORT)
      HlpTest_MainFunction();
# endif
    }
# if defined (BRS_ENABLE_TCM_SUPPORT) && !defined (BRSASR_ENABLE_OSSUPPORT)
    Tcm_BackgroundFunction();
# endif
  }
}
#endif /*BRS_ENABLE_SUPPORT_LEDS||BRS_ENABLE_TCM_SUPPORT||BRS_ENABLE_HLPTEST_SUPPORT*/
#if 0
#if defined (BRSASR_ENABLE_OSSUPPORT)
TASK(backgroundTask)
{
  for(;;)
  {
# if defined (_MICROSOFT_C_VTT_)
    CANoeAPI_ConsumeTicks(100);
# endif

# if defined (BRS_ENABLE_TCM_SUPPORT)
    Tcm_BackgroundFunction();
# endif
    (void)Schedule();
  }
}

# if defined (BRSASR_ENABLE_SAFEWDGSUPPORT)
/***********************************************************************************************************************
 *  WdgStack_ASILD_Task
 **********************************************************************************************************************/
/*! \brief      Initialization / Cyclic triggering of Safe Watch Dog (trusted code)
 *              
 *  \param[in]  -
 *  \param[out] -
 *  \return     -
 *  \context    The task is started once by the OS looping forever unless the OS processes interrupts or 
 *              tasks with higher priority
 *              The task activated by the OS event WdgStack_ASILD_Alarm
  **********************************************************************************************************************/
TASK(WdgStack_ASILD_Task)
{
  EventMaskType ev;

  BrsAsrInit_SafeWdg();

  (void)SetRelAlarm(WdgStack_ASILD_Alarm, OS_MS2TICKS_SystemTimer(1), OS_MS2TICKS_SystemTimer(10));

  for(;;)
  {
    (void)WaitEvent(WdgStack_ASILD_Event);
    (void)GetEvent(WdgStack_ASILD_Task, &ev);
    (void)ClearEvent(ev);

    WdgM_MainFunction();
  }
}

#  if defined (BRSASR_ENABLE_SAFEWDG_MULTICORESUPPORT)
TASK(WdgStack_ASILD_Task_Core1)
{
  EventMaskType ev;

  BrsAsrInit_SafeWdg_Core1();

  (void)SetRelAlarm(WdgStack_ASILD_Alarm_Core1, OS_MS2TICKS_SystemTimer(1), OS_MS2TICKS_SystemTimer(10));

  for(;;)
  {
    (void)WaitEvent(WdgStack_ASILD_Event_Core1);
    (void)GetEvent(WdgStack_ASILD_Task_Core1, &ev);
    (void)ClearEvent(ev);

    WdgM_MainFunction();
  }
}

TASK(WdgStack_ASILD_Task_Core2)
{
  EventMaskType ev;

  BrsAsrInit_SafeWdg_Core2();

  (void)SetRelAlarm(WdgStack_ASILD_Alarm_Core2, OS_MS2TICKS_SystemTimer(1), OS_MS2TICKS_SystemTimer(10));

  for(;;)
  {
    (void)WaitEvent(WdgStack_ASILD_Event_Core2);
    (void)GetEvent(WdgStack_ASILD_Task_Core2, &ev);
    (void)ClearEvent(ev);
    
    WdgM_MainFunction();
  }
}
#  endif /*BRSASR_ENABLE_SAFEWDG_MULTICORESUPPORT*/
# endif /*BRSASR_ENABLE_SAFEWDGSUPPORT*/
#endif /*BRSASR_ENABLE_OSSUPPORT*/

#if defined (BRSASR_ENABLE_SAFEWDGSUPPORT)
/* Necessary APIs for Interrupt handling in TTTech WdgM */
void GlobalSuspendInterrupts(void){
  SuspendAllInterrupts();
}

void GlobalRestoreInterrupts(void){
  ResumeAllInterrupts();
}
#endif /*BRSASR_ENABLE_SAFEWDGSUPPORT*/

#endif
